package com.quectel.emp.controller.app;

import com.quectel.business.common.thirdconfig.ThirdPlatformConfigBusiness;
import com.quectel.constant.global.SMSConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.dept.dto.DeptPersonDto;
import com.quectel.core.module.dept.service.DeptPersonService;
import com.quectel.core.module.officialaccounts.service.OfficialAccountsBindingService;
import com.quectel.core.module.village.dto.VillageDto;
import com.quectel.core.module.village.service.VillageService;
import com.quectel.emp.constants.EmpRedisCacheConstants;
import com.quectel.emp.controller.BaseController;
import com.quectel.emp.interceptor.LoginEmpSession;
import com.quectel.emp.util.SessionHolder;
import com.quectel.emp.util.SmsComponent;
import com.quectel.emp.vo.deptperson.login.AccountPasswordLoginVo;
import com.quectel.emp.vo.deptperson.login.AppVerCodeLoginVo;
import com.quectel.emp.vo.deptperson.login.SendVerCodeVo;
import com.quectel.sys.module.sys.service.SysTenantService;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.common.PasswordUtils;
import com.quectel.util.common.Response;
import com.quectel.util.redis.RedisUtils;
import com.quectel.util.security.TokenUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @author caolu
 * @email louis.cao@quectel.com
 */
@RestController
@RequestMapping("appDeptPerson")
@Tag(name = "AppDeptPersonController", description = "app员工登录修改等相关的api")
public class AppDeptPersonController extends BaseController {
    @DubboReference
    private VillageService villageService;
    @DubboReference
    private DeptPersonService deptPersonService;
    @DubboReference
    private OfficialAccountsBindingService officialAccountsBindingService;
    @DubboReference
    private SysTenantService sysTenantService;
    @Autowired
    private SmsComponent smsCompnent;

    @Autowired
    private ThirdPlatformConfigBusiness thirdPlatformConfigBusiness;


    /**
     * 发送验证码
     *
     * @return
     */
    @PostMapping("sendVerCodeLoginMsgCode")
    @Operation(summary = "发送验证码登录")
    public Response<Object> sendBindingMsgCode(@RequestBody SendVerCodeVo sendVerCodeVo) {

        VillageDto villageDto = villageService.selectByCode(sendVerCodeVo.getVillageCode());
        if (villageDto == null) {
            return Response.error("社区不存在，请检查访问链接");
        }
        DeptPersonDto deptPersonDto = deptPersonService.selectByVillageAndMobile(villageDto.getId(), sendVerCodeVo.getMobile());
        if (deptPersonDto == null) {
            return Response.error("您的个人信息不存在，请联系管理员添加");
        }
        if (SystemConstants.ABNORMAL.equals(deptPersonDto.getStatus())) {
            return Response.error("用户已被禁用");
        }

        String code = smsCompnent.sendVerCode(villageDto.getTenantId(), sendVerCodeVo.getMobile(), SMSConstants.VerCodeType.EMP_APP_VER_CODE_LOGIN);
        if (code == null) {
            return Response.error("发送验证码失败");
        }

        return Response.ok().wrap(thirdPlatformConfigBusiness.smsMockEnable(villageDto.getTenantId()) ? code : null);
    }

    /**
     * 验证码登录
     *
     * @return
     */
    @PostMapping("verCodeLogin")
    @Operation(summary = "验证码登录")
    public Response<LoginEmpSession> verCodeLogin(@RequestBody AppVerCodeLoginVo appVerCodeLoginVo) {

        boolean isLegal = smsCompnent.checkVerCode(appVerCodeLoginVo.getMobile(), appVerCodeLoginVo.getVerCode(), SMSConstants.VerCodeType.EMP_APP_VER_CODE_LOGIN);

        if (!isLegal) {
            //输入错误就要作废
            smsCompnent.invalidVerCode(appVerCodeLoginVo.getMobile(), SMSConstants.VerCodeType.EMP_APP_VER_CODE_LOGIN);
            return Response.error("您输入验证码不正确或者不在有效期内,请重新发送");
        }
        //使用以后过期
        smsCompnent.invalidVerCode(appVerCodeLoginVo.getMobile(), SMSConstants.VerCodeType.EMP_APP_VER_CODE_LOGIN);


        VillageDto villageDto = villageService.selectByCode(appVerCodeLoginVo.getVillageCode());
        if (villageDto == null) {
            return Response.error("社区不存在，请检查访问链接");
        }

        DeptPersonDto deptPersonDto = deptPersonService.selectByVillageAndMobile(villageDto.getId(), appVerCodeLoginVo.getMobile());
        if (deptPersonDto == null) {
            return Response.error("您的个人信息不存在，请联系管理员添加");
        }
        if (SystemConstants.ABNORMAL.equals(deptPersonDto.getStatus())) {
            return Response.error("用户已被禁用");
        }

        LoginEmpSession empSession = new LoginEmpSession();
        empSession.setLoginType(appVerCodeLoginVo.getLoginType());
        empSession.setToken(TokenUtils.genRandomToken());
        empSession.setDeptPersonDto(deptPersonDto);

        return Response.<LoginEmpSession>ok().wrap(SessionHolder.resetLoginEmpSession(empSession));
    }

    @PostMapping("accountPasswordLogin")
    @Operation(summary = "app账号密码登录")
    public Response<LoginEmpSession> accountPasswordLogin(@RequestBody AccountPasswordLoginVo loginVo) {

        logger.debug("jsapi账号密码登录，请求参数：" + JacksonUtils.toJsonString(loginVo));

        String generateCode = RedisUtils.get(EmpRedisCacheConstants.CAPTCHA_ID + loginVo.getCaptchaId());
        if (StringUtils.isBlank(generateCode)) {
            return Response.error("验证码过期");
        }

        if (!StringUtils.equalsIgnoreCase(generateCode, loginVo.getCaptcha())) {
            return Response.error("验证码错误");
        }

        VillageDto villageDto = villageService.selectByCode(loginVo.getVillageCode());
        if (villageDto == null) {
            return Response.error("当前社区不存在");
        }

        DeptPersonDto dbPerson = deptPersonService.selectByVillageAndMobile(villageDto.getId(), loginVo.getMobile());
        if (dbPerson == null) {
            return Response.error("当前用户不存在");
        }
        if (SystemConstants.NO.equals(dbPerson.getStatus())) {
            return Response.error("当前用户已锁定");
        }
        String wrongCount = RedisUtils.get(EmpRedisCacheConstants.WRONG_INPUT + dbPerson.getId());
        if (StringUtils.isNotBlank(wrongCount) && Long.valueOf(wrongCount) >= EmpRedisCacheConstants.WRONG_NUM) {
            Long ttl = RedisUtils.ttl(EmpRedisCacheConstants.WRONG_INPUT + dbPerson.getId(), TimeUnit.MINUTES);
            return Response.error("该账户已被冻结，请在：" + (ttl <= 0 ? 1 : ttl) + "分钟后登录");
        }
        if (loginVo.getPassword() == null || !PasswordUtils.matchPassword(loginVo.getPassword(), dbPerson.getPassword())) {

            long incr = RedisUtils.incr(EmpRedisCacheConstants.WRONG_INPUT + dbPerson.getId(), 1, EmpRedisCacheConstants.WRONG_LOCK_SECOND, TimeUnit.SECONDS);
            if (incr >= EmpRedisCacheConstants.WRONG_NUM) {
                Long ttl = RedisUtils.ttl(EmpRedisCacheConstants.WRONG_INPUT + dbPerson.getId(), TimeUnit.MINUTES);
                return Response.error("该账户已被冻结，请在：" + (ttl <= 0 ? 1 : ttl) + "分钟后登录");
            }
            return Response.error("密码错误 错误" + (EmpRedisCacheConstants.WRONG_NUM - incr) + "次后该账户将被冻结" + EmpRedisCacheConstants.WRONG_LOCK_SECOND / 60 + "分钟");
        }
        //删除锁定次数
        RedisUtils.del(EmpRedisCacheConstants.WRONG_INPUT + dbPerson.getId());

        LoginEmpSession session = new LoginEmpSession();
        session.setLoginType(loginVo.getLoginType());
        session.setToken(TokenUtils.genRandomToken());
        session.setDeptPersonDto(dbPerson);

        return Response.<LoginEmpSession>ok().wrap(SessionHolder.resetLoginEmpSession(session));
    }


}
